#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "MyVector.h"

#define true 1
#define false 0

//初始化,创建指针
DMArray* DMArray_Init_pointer()
{
    DMArray* arr = (DMArray*)malloc(sizeof(DMArray));
    if(arr == NULL)
    {
        printf("DMArray_Init malloc error!\n");
        return NULL;
    }
    arr->dp = (ElementType*)malloc(sizeof(ElementType) * DEAULT_CAPACITY);
    if(arr->dp == NULL)
    {
        printf("DMArray_Init_element mallc error!\n");
        return NULL;
    }
    arr->capacity = DEAULT_CAPACITY;
    arr->size = 0;
    return arr;
}

//初始化
void DMArray_Init(DMArray* arr)
{
    arr->dp = (ElementType*)malloc(sizeof(ElementType) * DEAULT_CAPACITY);
    if(arr->dp == NULL)
    {
        printf("DMArray_Init_element mallc error!\n");
        return;
    }
    arr->capacity = DEAULT_CAPACITY;
    arr->size = 0;
}

//销毁
void DMArray_Destroy(DMArray* arr)
{
    if(arr == NULL)
    {
        return;
    }
    if(arr->dp != NULL)
    {
        free(arr->dp);
        arr->dp = NULL;
    }
    free(arr);
    arr = NULL;
}

//遍历
void DMArray_Travel(DMArray* arr, void(*PrintCallBack)(ElementType) )
{
    if(arr == NULL || PrintCallBack == NULL) 
    {
        return;
    }
    for(int i = 0; i < arr->size; ++i)
        PrintCallBack(arr->dp[i]);
    printf("\n");
}

//memcpy函数的实现
void* my_memcpy(void* dst, const void* src, unsigned int count)
{
    void* ret = dst;
    while(--count)
    {
        *(char*) dst = *(char*) src;//  *(char*) str =  *((char*) + 0)
        dst = (char*)dst + 1;
        src = (char*)src + 1;
    }
    return ret;
}

//扩容
int DMArray_ExtendCapacity(DMArray* arr)
{
     //重新申请堆内存
        ElementType* newSpace = (ElementType*)malloc(sizeof(ElementType) * arr->capacity * 2);
        if(newSpace == NULL)
        {
            printf("Exspansion failure!\n");
            return false;
        } 
        //原数据copy到新的堆内存
        my_memcpy(newSpace, arr->dp, sizeof(ElementType*) * arr->capacity);
        free(arr->dp);     //释放旧内存
        arr->dp = newSpace;//更新新指向
        newSpace = NULL;   //将新生成的指针指向空
        arr->capacity = arr->capacity * 2;//更新容量
        return true;
}

//尾插
void DMArray_PushBack(DMArray* arr, ElementType element)
{
    DMArray_InsertByIndex(arr, arr->size, element); 
}

//头插
void DMArray_PushFront(DMArray* arr, ElementType element)
{
    DMArray_InsertByIndex(arr, 0, element);  
}

//动态数组在index处插入数据element
void DMArray_InsertByIndex(DMArray* arr, int index, ElementType element)
{
    if(arr == NULL || element == NULL)
        return;
    if(index < 0 || index >= arr->size)//插入索引不在[0,size)内时，选择尾插
        index = arr->size;
    if(arr->size == arr->capacity)
    {
        DMArray_ExtendCapacity(arr);
    }
    for(int i = arr->size - 1; i >= index; --i) //更新数据插入到index，先后移index及其以后数据
        arr->dp[i+1] = arr->dp[i];              //dp[i]相当于*(dp+i),dp原为二级指针，
    arr->dp[index] = element;                   //解引用操作了void*,使得一级指针后移
    arr->size++;
} 

//根据位置删除
void DMArray_RemoveByIndex(DMArray* arr, int index)
{
    if(arr == NULL)
    {
        printf("Dynamic Array is empty!\n");
        return;
    }
    if(index < 0 || index > arr->size - 1)
    {
        printf("DMArray_RemoveByIndex invalid parameter!\n");
        return;
    }
    for(int i = index; i < arr->size - 1; ++i)
    {
        arr->dp[i] = arr->dp[i+1];
    }
    arr->size--;   
}

//根据值删除
void DMArray_RemoveByElement(DMArray* arr, ElementType element, int (*compare)(void* s1, void* s2))
{
    if(arr == NULL)
    {
        printf("Dynamic Array is empty!\n");
        return;
    }
    int* findVector = DMArray_FindByElement(arr, element, compare);
    for(int i = 0; findVector[i] != -1; ++i)
    {
        DMArray_RemoveByIndex(arr, findVector[i]);
    }
}

//根据下标返回值
ElementType DMArray_FindByIndex(DMArray* arr, int index)
{
    if(arr == NULL)
    {
        printf("Dynamic Array is empty!\n");
        exit(1);
    }
    return arr->dp[index];
}

//查找值返回下标
int* DMArray_FindByElement(DMArray* arr, ElementType element, int (*compare)(void* s1, void* s2))//仅在不重复的情况下考虑
{
    if(arr == NULL || element == NULL)
    {   
        printf("Invalid parameter!\n");
        return NULL;
    }
    int j = 0;
    int* findVector = (int*)malloc(sizeof(int) * (arr->size + 1));
    for(int i = 0; i < arr->size; ++i)//利用函数回调找出与element相同时的索引index
    {
        if(compare(arr->dp[i], element))
            findVector[j++] = i;
    }
    findVector[j] = -1;
    return findVector; 
}

//清空数组
void DMArray_Clear(DMArray* arr)
{
    if(arr == NULL)
        return;
    arr->size = 0;
}

//获取动态数组容量
int DMArray_GetCapacity(DMArray* arr)
{
    return arr->capacity;
}

//获取动态数组当前元素个数
int DMArray_GetSize(DMArray* arr)
{
    return arr->size;
}

//判断是否为空
int DMArray_IsEmpty(DMArray* arr)
{
    return arr->size == 0 && arr->dp == NULL;
}

//打印函数的具体实现
void DMArray_Print_int(ElementType data)
{   
    int* IntNum = (int*)data;
    if(IntNum)
       printf("%d ", *IntNum);
} 